package uit.com.project.iCampus.activity;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import uit.com.project.iCampus.Util.Util;
import uit.com.project.iCampus.application.ICampusApp;
import uit.com.project.iCampus.map.CircleAreaOverlay;
import uit.com.project.iCampus.map.MapDirectionOverlay;
import uit.com.project.iCampus.map.NearestBuildingCenterOverlay;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.InputType;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

@SuppressLint("HandlerLeak")
public class BuildingCenterNearestMapActivity extends MapActivity implements LocationListener {
	MapView mapView;
	MapController mc;
	
	// Popup option menu
	LinearLayout optionMenu_layout;
	EditText changeRadius_edit;
	boolean op_building_checkbox_value;
	boolean op_busstop_checkbox_value ;
	boolean op_food_checkbox_value;
	boolean op_softdrink_checkbox_value;
	boolean op_University_checkbox_value;
	static int countOverlays = 0;
	
	
	GeoPoint p;
	
	long medicalCenterId;
	
	GeoPoint topRightPoint, botLeftPoint;
	
	float fromLat, fromLon, toLat, toLon;

	static final private int MENU_ITEM = Menu.FIRST;
	static final int DRAW_DIRECTION = 0; 
	static final int UPDATE_GPS_LOCATION = 1;
	List<Overlay> listOfOverlays = null;

	Menu menu = null;

	private LocationManager lm;
	private List<GeoPoint> pointToPointDraws = new ArrayList<GeoPoint>();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.medicalcenter_nearest_map);
		findViewById(R.id.nearest_getDirectionDescription).setVisibility(View.INVISIBLE);
		ICampusApp.DESTINATION = null;
		
		// ---use the LocationManager class to obtain GPS locations---
		lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 500.0f,
				this);
		
		ICampusApp.PROGRESS_DIALOG = ProgressDialog.show(this, "", getResources().getString(R.string.pleaseWait), true, true);

		mapView = (MapView) findViewById(R.id.mapView);
//		mapView.setStreetView(true);
		mapView.setBuiltInZoomControls(true);
		mapView.displayZoomControls(true);
		mapView.getZoomButtonsController().setAutoDismissed(false);
		mapView.getZoomButtonsController().setVisible(true);


		mc = mapView.getController();
		ICampusApp.SHOW_DIRECTION_PATH = false;
	}
	
	public void initMapView(){
		//Get list medical center in area
		Util.searchMedicalCenterInArea(mapView);
		
		Drawable buildingFoodsMarker = getResources().getDrawable(R.drawable.dot_food);
		Drawable buildingTramsMarker = getResources().getDrawable(R.drawable.dot_bus);
		Drawable buildingUniversityMarker = getResources().getDrawable(R.drawable.dot_uni);
		Drawable buildingSoftDrinkMarker = getResources().getDrawable(R.drawable.dot_sd);
		Drawable buildingMarker = getResources().getDrawable(R.drawable.dot_build);
		
		CircleAreaOverlay circleOverlay = new CircleAreaOverlay(BuildingCenterNearestMapActivity.this, ICampusApp.CIRCLE_RADIUS);
		NearestBuildingCenterOverlay buildingFoodsOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_FOOD_IN_AREA, buildingFoodsMarker);
		NearestBuildingCenterOverlay buildingTramsOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_TRAMS_IN_AREA, buildingTramsMarker);
		NearestBuildingCenterOverlay buildingUniversityOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_University_IN_AREA, buildingUniversityMarker);
		NearestBuildingCenterOverlay buildingSoftDrinkOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_Softdrink_IN_AREA, buildingSoftDrinkMarker);
		NearestBuildingCenterOverlay buildingOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_HighBuilding_IN_AREA, buildingMarker);
		listOfOverlays = mapView.getOverlays();
		listOfOverlays.clear();
		listOfOverlays.add(circleOverlay);
		countOverlays = 1;
		 if (op_food_checkbox_value) {
 			listOfOverlays.add(buildingFoodsOverlay);
 			countOverlays++;
 		}
 		if (op_building_checkbox_value) {
 			listOfOverlays.add(buildingOverlay);
 			countOverlays++;
		}
 		if (op_busstop_checkbox_value) {
 			listOfOverlays.add(buildingTramsOverlay);
 			countOverlays++;
		}
 		if (op_softdrink_checkbox_value) {
 			listOfOverlays.add(buildingSoftDrinkOverlay);
 			countOverlays++;
		}
 		if (op_University_checkbox_value) {
 			listOfOverlays.add(buildingUniversityOverlay);
 			countOverlays++;
		}
		
		mc = mapView.getController();
		mc.setZoom(15);
		mc.animateTo(ICampusApp.MY_LOCATION);
		mapView.invalidate();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);

		// Group ID
		int groupId = 0;

		// Unique menu item identifier. Used for event handling.
		int menuItemId = MENU_ITEM;

		// The order position of the item
		int menuItemOrder = Menu.NONE;
		this.menu = menu;

		menu.add(groupId, menuItemId + 0, menuItemOrder,
				getString(R.string.getDirection)).setIcon(R.drawable.get_direction);
//		menu.add(groupId, menuItemId + 1, menuItemOrder,
//				getString(R.string.back)).setIcon(R.drawable.back);
		menu.add(groupId, menuItemId + 1, menuItemOrder,
				getString(R.string.changeRadius)).setIcon(R.drawable.change_radius);
		
		return true;
	}

	// process event select Menu
	public boolean onOptionsItemSelected(MenuItem item) {
		super.onOptionsItemSelected(item);

		// Find which menu item has been selected
		switch (item.getItemId()) {
		case (MENU_ITEM + 0): {
			if (ICampusApp.DESTINATION != null) {
				getDirection();
				break;
			} else {
				Util.showAlert(this, getResources().getString(R.string.warning), getResources().getString(R.string.selectMedicalCenter));
				break;
			}
		}
		case (MENU_ITEM + 1): {
			View optionMenu = getLayoutInflater().inflate(R.layout.option_menu, null);
			changeRadius_edit = (EditText) optionMenu.findViewById(R.id.radiusTextView);
			changeRadius_edit.setText(ICampusApp.CIRCLE_RADIUS + "");
			changeRadius_edit.setSingleLine(true);
			changeRadius_edit.setInputType(InputType.TYPE_CLASS_NUMBER);
			
			final CheckBox op_building_checkbox = (CheckBox)optionMenu.findViewById(R.id.op_building);
			final CheckBox op_busstop_checkbox = (CheckBox)optionMenu.findViewById(R.id.op_busstop);
			final CheckBox op_food_checkbox =(CheckBox)optionMenu.findViewById(R.id.op_food);
			final CheckBox op_softdrink_checkbox = (CheckBox)optionMenu.findViewById(R.id.op_softdrink);
			final CheckBox op_University_checkbox =(CheckBox)optionMenu.findViewById(R.id.op_University);
			
			new AlertDialog.Builder(BuildingCenterNearestMapActivity.this)
		    .setTitle(getResources().getString(R.string.changeRadiusTitle))
		    .setView(optionMenu)
		    .setPositiveButton(getResources().getString(R.string.accept), new DialogInterface.OnClickListener() {
		        public void onClick(DialogInterface dialog, int whichButton) {
		            String value = changeRadius_edit.getText().toString();
		            op_building_checkbox_value = op_building_checkbox.isChecked();
		            op_busstop_checkbox_value = op_busstop_checkbox.isChecked();
		            op_food_checkbox_value = op_food_checkbox.isChecked();
		            op_softdrink_checkbox_value = op_softdrink_checkbox.isChecked();
		            op_University_checkbox_value = op_University_checkbox.isChecked();
		            try {
		            	ICampusApp.CIRCLE_RADIUS = Integer.parseInt(value);
		            	Util.searchMedicalCenterInArea(mapView);
		            	
		            	Drawable buildingFoodsMarker = getResources().getDrawable(R.drawable.dot_food);
		        		Drawable buildingTramsMarker = getResources().getDrawable(R.drawable.dot_bus);
		        		Drawable buildingUniversityMarker = getResources().getDrawable(R.drawable.dot_uni);
		        		Drawable buildingSoftDrinkMarker = getResources().getDrawable(R.drawable.dot_sd);
		        		Drawable buildingMarker = getResources().getDrawable(R.drawable.dot_build);
		        		
		        		CircleAreaOverlay circleOverlay = new CircleAreaOverlay(BuildingCenterNearestMapActivity.this, ICampusApp.CIRCLE_RADIUS);
		        		NearestBuildingCenterOverlay buildingFoodsOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_FOOD_IN_AREA, buildingFoodsMarker);
		        		NearestBuildingCenterOverlay buildingTramsOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_TRAMS_IN_AREA, buildingTramsMarker);
		        		NearestBuildingCenterOverlay buildingUniversityOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_University_IN_AREA, buildingUniversityMarker);
		        		NearestBuildingCenterOverlay buildingSoftDrinkOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_Softdrink_IN_AREA, buildingSoftDrinkMarker);
		        		NearestBuildingCenterOverlay buildingOverlay = new NearestBuildingCenterOverlay(BuildingCenterNearestMapActivity.this, mapView, ICampusApp.LIST_BUILDING_HighBuilding_IN_AREA, buildingMarker);
		        		listOfOverlays = mapView.getOverlays();
		        		listOfOverlays.clear();
		        		listOfOverlays.add(circleOverlay);
		        		countOverlays = 1;
		        		if (op_food_checkbox_value) {
		        			listOfOverlays.add(buildingFoodsOverlay);
		        			countOverlays++;
		        		}
		        		if (op_building_checkbox_value) {
		        			listOfOverlays.add(buildingOverlay);
		        			countOverlays++;
						}
		        		if (op_busstop_checkbox_value) {
		        			listOfOverlays.add(buildingTramsOverlay);
		        			countOverlays++;
						}
		        		if (op_softdrink_checkbox_value) {
		        			listOfOverlays.add(buildingSoftDrinkOverlay);
		        			countOverlays++;
						}
		        		if (op_University_checkbox_value) {
		        			listOfOverlays.add(buildingUniversityOverlay);
		        			countOverlays++;
						}
		        		
		        		mc = mapView.getController();
		        		mc.setZoom(15);
		        		mc.animateTo(ICampusApp.MY_LOCATION);
		        		mapView.invalidate();
		            } catch (NumberFormatException e) {
		            	Util.showAlert(BuildingCenterNearestMapActivity.this, getResources().getString(R.string.warning), getResources().getString(R.string.warningIntegerInput));
					}
		        }
		    }).setNegativeButton(getResources().getString(R.string.back), new DialogInterface.OnClickListener() {
		        public void onClick(DialogInterface dialog, int whichButton) {
		            // Do nothing.
		        }
		    }).show();
		}
		}
		return true;
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void onLocationChanged(Location location) {
		if (location != null) {
			fromLat = (float) location.getLatitude();
			fromLon = (float) location.getLongitude();
			ICampusApp.MY_LOCATION = new GeoPoint((int) (fromLat * 1E6), (int) (fromLon * 1E6));
			mHandler.sendEmptyMessage(UPDATE_GPS_LOCATION);
			Log.i(" User location changed to: ", ICampusApp.MY_LOCATION.getLatitudeE6() + " " + ICampusApp.MY_LOCATION.getLongitudeE6() );
			initMapView();
		}
	}

	@Override
	public void onProviderDisabled(String arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		// TODO Auto-generated method stub

	}

	public void getDirection() {
		ICampusApp.PROGRESS_DIALOG = ProgressDialog.show(this, "", getResources().getString(R.string.pleaseWait), true, true);
		new Thread() {
			@Override
			public void run() {
				try {
					fromLat = (float)(ICampusApp.MY_LOCATION.getLatitudeE6() / 1E6);
					fromLon = (float)(ICampusApp.MY_LOCATION.getLongitudeE6() / 1E6);
					toLat = (float) (ICampusApp.DESTINATION.getLatitudeE6() / 1E6);
					toLon = (float) (ICampusApp.DESTINATION.getLongitudeE6() / 1E6);
					
					String url = "http://maps.googleapis.com/maps/api/directions/json?origin=" +
							fromLat + "," + fromLon +"&destination=" + toLat + "," + toLon + "&sensor=false";
					DefaultHttpClient httpClient = new DefaultHttpClient();
					HttpPost httppost = new HttpPost(url);
					
					HttpResponse response = httpClient.execute(httppost);
					HttpEntity entity = response.getEntity();
					InputStream is = null;
					is = entity.getContent();
					BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
					StringBuilder sb = new StringBuilder();
					sb.append(reader.readLine() + "\n");
					String line = "0";
					while ((line = reader.readLine()) != null) {
					    sb.append(line + "\n");
					}
					is.close();
					reader.close();
					String result = sb.toString();
					JSONObject jsonObject = new JSONObject(result);
					JSONArray routeArray = jsonObject.getJSONArray("routes");
					JSONObject routes = routeArray.getJSONObject(0);
					JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
					String encodedString = overviewPolylines.getString("points");
					pointToPointDraws = decodePoly(encodedString);
					mHandler.sendEmptyMessage(DRAW_DIRECTION);
				} catch (Exception e) {
					mHandler.sendEmptyMessage(-1);
					e.printStackTrace();
				}
			}
		}.start();
	}
	
	//code for get direction
	private List<GeoPoint> decodePoly(String encoded) {

	    List<GeoPoint> poly = new ArrayList<GeoPoint>();
	    int index = 0, len = encoded.length();
	    int lat = 0, lng = 0;

	    while (index < len) {
	        int b, shift = 0, result = 0;
	        do {
	            b = encoded.charAt(index++) - 63;
	            result |= (b & 0x1f) << shift;
	            shift += 5;
	        } while (b >= 0x20);
	        int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
	        lat += dlat;

	        shift = 0;
	        result = 0;
	        do {
	            b = encoded.charAt(index++) - 63;
	            result |= (b & 0x1f) << shift;
	            shift += 5;
	        } while (b >= 0x20);
	        int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
	        lng += dlng;

	        GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6), (int) (((double) lng / 1E5) * 1E6));
	        poly.add(p);
	    }
	    return poly;
	}
	Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (ICampusApp.PROGRESS_DIALOG != null){
				ICampusApp.PROGRESS_DIALOG.dismiss();
				ICampusApp.PROGRESS_DIALOG = null;
			}
			
			if (msg.what == -1){
				Util.showAlert(BuildingCenterNearestMapActivity.this, getResources().getString(R.string.connectionErrorTitle), getResources().getString(R.string.connectionErrorContent));
			} else if (msg.what == DRAW_DIRECTION){
//				TextView textView = (TextView) findViewById(R.id.nearest_getDirectionDescription);
//				textView.setText("name" + "\n" + "decription");
				ICampusApp.SHOW_DIRECTION_PATH = true;
				
				//Added line:
				MapDirectionOverlay directionOverlay = new MapDirectionOverlay(pointToPointDraws);
				//Check whether MapDirectionOverlay has exists?
				int ziseOfListOverlay = listOfOverlays.size();
				Log.i("ziseOfListOverlay", ziseOfListOverlay + "");
				Log.i("countOverlays", countOverlays + "");
				if (ziseOfListOverlay > countOverlays){
					listOfOverlays.remove(ziseOfListOverlay -1);
				}
				listOfOverlays.add(directionOverlay);
				mc.setZoom(15);
				mapView.invalidate();
			}
		};
	};

	
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (event.getAction() == KeyEvent.ACTION_DOWN) {
			switch (keyCode) {
			case KeyEvent.KEYCODE_BACK :
//				Intent i = new Intent(MedicalCenterNearestMap.this,
//						HealthSystem.class);
//				startActivity(i);
//				finish();
			}
		}
		return super.onKeyDown(keyCode, event);
	}

}
